#include "dxyReflectClass.h"

namespace dxy {
namespace reflect {

    DxyRelfectObject::~DxyRelfectObject() {}

    DxyReflectClass & DxyReflectClass::getInstance()
    {
        static DxyReflectClass instance;
        return instance;
    }

    DxyReflectClass::DxyReflectClass()
    {

    }

    DxyReflectClass::~DxyReflectClass()
    {
        #ifdef _WIN32
            exit(0); // ？？？ Windows 出现库无法正常析构的问题
        #endif
    }

    std::unique_ptr<DxyRelfectObject> DxyReflectClass::getClassByName(const std::string & className)
    {
        auto it = m_classMap.find(className);
        if(it == m_classMap.end())
        {
            return nullptr;
        }
        return std::unique_ptr<DxyRelfectObject>(it->second());
    }

    void DxyReflectClass::registerClassFieldByName(const std::string & className, const std::string & fieldName, size_t offset)
    {
        auto it = m_classMap.find(className);
        if(it == m_classMap.end()) throw std::runtime_error("Can not find class");
        if(m_classFieldMap.find(className) == m_classFieldMap.end())
        {
            m_classFieldMap[className] = std::map<std::string, size_t>();
        }
        m_classFieldMap[className][fieldName] = offset;
    }

    void DxyReflectClass::registerClassFunctionByName(const std::string & className, const std::string & funcName, size_t ptr)
    {
        auto it = m_classMap.find(className);
        if(it == m_classMap.end()) throw std::runtime_error("Can not find class");
        if(m_classFunctionMap.find(className) == m_classFunctionMap.end())
        {
            m_classFunctionMap[className] = std::map<std::string, size_t>();
        }
        m_classFunctionMap[className][funcName] = ptr;
    }

    void DxyRelfectObject::call(const std::string & className, const std::string & funcName)
    {
        auto it1 = DxyReflectClass::getInstance().m_classFunctionMap.find(className);
        if(it1 == DxyReflectClass::getInstance().m_classFunctionMap.end()) throw std::runtime_error("Can not find class");
        auto it2 = DxyReflectClass::getInstance().m_classFunctionMap[className].find(funcName);
        if(it2 == DxyReflectClass::getInstance().m_classFunctionMap[className].end()) throw std::runtime_error("Can not find function");
        std::function<void (decltype(this))> func = *(std::function<void (decltype(this))>*)(it2->second);
        func(this);
    }



}
}
